﻿using System;
using System.Collections.Generic;

namespace YinLongTool.Ui
{
	public class AppReportManager
	{
		/// <summary>
		/// 带返回值
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="e"></param>
		/// <returns></returns>
        public delegate string EventDelegateString<T>(T e) where T : EventArgs;
		/// <summary>
		/// 无返回值
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="e"></param>
		public delegate void EventDelegateVoid<T>(T e) where T : EventArgs;
		public static readonly AppReportManager Instance = new AppReportManager();
		private readonly Dictionary<Type, Delegate> _delegates = new Dictionary<Type, Delegate>();
		private AppReportManager()
		{
		}
		/// <summary>
		/// 添加监听
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="listener"></param>
		public void AddListenerVoid<T>(AppReportManager.EventDelegateVoid<T> listener) where T : EventArgs
		{
			Delegate a;
			if (this._delegates.TryGetValue(typeof(T), out a))
			{
				this._delegates[typeof(T)] = Delegate.Combine(a, listener);
			}
			else
			{
				this._delegates[typeof(T)] = listener;
			}
		}
		/// <summary>
		/// 删除监听
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="listener"></param>
		public void RemoveListenerVoid<T>(AppReportManager.EventDelegateVoid<T> listener) where T : EventArgs
		{
			Delegate source;
			if (this._delegates.TryGetValue(typeof(T), out source))
			{
				Delegate @delegate = Delegate.Remove(source, listener);
				if (@delegate == null)
				{
					this._delegates.Remove(typeof(T));
				}
				else
				{
					this._delegates[typeof(T)] = @delegate;
				}
			}
		}
		/// <summary>
		/// 回调
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="e"></param>
		public void SendVoid<T>(T e) where T : EventArgs
		{
			if (e == null)
			{
				throw new ArgumentNullException("e");
			}
			Delegate @delegate;
			if (this._delegates.TryGetValue(typeof(T), out @delegate))
			{
				AppReportManager.EventDelegateVoid<T> eventDelegate = @delegate as AppReportManager.EventDelegateVoid<T>;
				if (eventDelegate != null)
				{
					eventDelegate(e);
				}
			}
		}
		/// <summary>
		/// 添加
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="listener"></param>
        public void AddListener<T>(AppReportManager.EventDelegateString<T> listener) where T : EventArgs
        {
            Delegate a;
            if (this._delegates.TryGetValue(typeof(T), out a))
            {
                this._delegates[typeof(T)] = Delegate.Combine(a, listener);
            }
            else
            {
                this._delegates[typeof(T)] = listener;
            }
        }
		/// <summary>
		/// 删除
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="listener"></param>
        public void RemoveListener<T>(AppReportManager.EventDelegateString<T> listener) where T : EventArgs
        {
            Delegate source;
            if (this._delegates.TryGetValue(typeof(T), out source))
            {
                Delegate @delegate = Delegate.Remove(source, listener);
                if (@delegate == null)
                {
                    this._delegates.Remove(typeof(T));
                }
                else
                {
                    this._delegates[typeof(T)] = @delegate;
                }
            }
        }
		/// <summary>
		/// 回调
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="e"></param>
		/// <returns></returns>
        public string Send<T>(T e) where T : EventArgs
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");
            }
            Delegate @delegate;
            if (this._delegates.TryGetValue(typeof(T), out @delegate))
            {
                AppReportManager.EventDelegateString<T> eventDelegate = @delegate as AppReportManager.EventDelegateString<T>;
                if (eventDelegate != null)
                {
                   return eventDelegate.Invoke(e);
                }
            }

            return "";
        }
	}
}
